package cn.tedu.bonfire.front.content.service.impl;

import cn.tedu.bonfire.common.enumerator.ServiceCode;
import cn.tedu.bonfire.common.ex.ServiceException;
import cn.tedu.bonfire.common.pojo.authentication.CurrentPrincipal;
import cn.tedu.bonfire.common.pojo.vo.PageData;
import cn.tedu.bonfire.front.content.dao.cache.ILikeCollectCacheRepository;
import cn.tedu.bonfire.front.content.dao.persist.repository.IArticleDetailRepository;
import cn.tedu.bonfire.front.content.dao.persist.repository.IArticleRepository;
import cn.tedu.bonfire.front.content.dao.persist.repository.ICategoryRepository;
import cn.tedu.bonfire.front.content.pojo.dto.ArticleAddNewDto;
import cn.tedu.bonfire.front.content.pojo.dto.UpdateArticleRequestDto;
import cn.tedu.bonfire.front.content.pojo.entity.Article;
import cn.tedu.bonfire.front.content.pojo.entity.ArticleDetail;
import cn.tedu.bonfire.front.content.pojo.vo.*;
import cn.tedu.bonfire.front.content.service.IArticleService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ArticleServiceImpl implements IArticleService {

    @Value("${bonfire.dao.default-query-page-size}")
    private Integer defaultQueryPageSize;

    @Autowired
    private IArticleRepository articleRepository;
    @Autowired
    private IArticleDetailRepository articleDetailRepository;
    @Autowired
    private ICategoryRepository categoryRepository;
    @Autowired
    private ILikeCollectCacheRepository likeCollectCacheRepository;

    @Override
    public Long selectUserArticles(Long userId) {
        log.debug("开始处理【根据ID查询用户文章数量】的业务，参数：{}", userId);
        return articleRepository.selectUserArticles(userId);
    }


    @Override
    public Long selectUserLikes(Long userId) {
        log.debug("开始处理【根据ID查询用户点赞量】的业务，参数：{}", userId);
        return articleRepository.selectUserLikes(userId);
    }

    @Override
    public Long selectUserViews(Long userId) {
        log.debug("开始处理【根据ID查询用户浏览量】的业务，参数：{}", userId);
        return articleRepository.selectUserViews(userId);
    }

    @Override
    public Long selectUserCollect(Long userId) {
        log.debug("开始处理【根据ID查询用户收藏数】的业务，参数：{}", userId);
        return articleRepository.selectUserCollect(userId);
    }
    @Override
    public void updateViewById(Long id) {
        log.debug("开始处理【浏览量】的业务，文章类别：{}, 页码：{}", id);
        articleRepository.updateViewById(id);
    }
    @Override
    public void addNew(CurrentPrincipal currentPrincipal, String remoteAddr,ArticleAddNewDto articleAddNewDto) {
        log.debug("开始处理【发布文章】的业务，当事人：{}，IP地址：{}，参数：{}", currentPrincipal, remoteAddr, articleAddNewDto);

        Long categoryId = articleAddNewDto.getCategoryId();
        CategoryStandardVO category = categoryRepository.getStandardById(categoryId);
        if (category == null) {
            String message = "发布文章失败，选择的类别不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        if (category.getEnable() != 1) {
            String message = "发布文章失败，选择的类别已经被禁用！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, message);
        }

        Article article = new Article();
        BeanUtils.copyProperties(articleAddNewDto, article);
        article.setAuthorId(currentPrincipal.getId());
        article.setAuthorName(currentPrincipal.getUsername());
        article.setCategoryName(category.getName());
        article.setIp(remoteAddr);
        article.setClickCount(0);
        article.setUpCount(0);
        article.setDownCount(0);
        article.setCheckState(CHECK_STATE_UNCHECKED);
        article.setIsRecommend(RECOMMEND_STATE_OFF);
        int rows = articleRepository.insert(article);
        if (rows != 1) {
            String message = "发布文章失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }

        ArticleDetail articleDetail = new ArticleDetail();
        articleDetail.setArticleId(article.getId());
        articleDetail.setDetail(articleAddNewDto.getDetail());
        rows = articleDetailRepository.insert(articleDetail);
        if (rows != 1) {
            String message = "发布文章失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_INSERT, message);
        }
    }





    @Override
    public PageData<ArticleListItemVO> listByRecommend() {
        return articleRepository.listByRecommend();
    }


    /*@Override
    public PageData<ArticleListItemVO> listByHot() {
        return articleRepository.listByHot();
    }*/

    /**
     * 笔记管理页面--根据id修改文章状态(公开或私密)
     *
     * @param updateArticleRequestDto 修改状态的参数
     * @return 受影响的行数
     */
    @Override
    public int updateArticle(CurrentPrincipal currentPrincipal, UpdateArticleRequestDto updateArticleRequestDto) {
        log.debug("开始处理【根据id修改文章状态】的业务，当事人：{}，参数：{}", currentPrincipal, updateArticleRequestDto);
        Article article = new Article();
        article.setId(updateArticleRequestDto.getId());
        article.setIsDisplay(updateArticleRequestDto.getIsDisplay());
        return articleRepository.updateArticle(article);
    }

    @Override
    public PageData<UserDraftListVO> selectdraft(Long userId,Integer pageNum,Integer pageSize) {
        return articleRepository.selectdraft(userId,pageNum,pageSize);
    }

    @Override
    public List<UserCollectListVO> selectMyAuditArticle(Long userId) {
        return articleRepository.selectMyAuditArticle(userId);
    }

    @Override
    public UserDraftListVO selectDraftDetail(Long authorId, Long articleId) {
        return articleRepository.selectDraftDetail(authorId, articleId);
    }

    @Override
    public ArticleStandardVO getStandardById(Long id) {
        log.debug("开始处理【根据ID查询文章】的业务，参数：{}", id);
        ArticleStandardVO queryResult = articleRepository.getStandardById(id);
        if (queryResult == null) {
            String message = "查询文章详情失败，文章数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        return queryResult;
    }


    @Override
    public PageData<ArticleListItemVO> listByCategory(Long categoryId, Integer isRecommend) {
        log.debug("开始处理【根据类别查询文章列表】的业务，文章内容: {}，是否推荐: {}", categoryId, isRecommend);
        return articleRepository.listByCategory(categoryId, isRecommend);
    }

    @Override
    public List<UserCollectListVO> selectMyArticle(Long userId) {

        return articleRepository.selectMyArticle(userId);
    }

    @Override
    public List<UserCollectListVO> getIsrecommend() {
        return articleRepository.getIsrecommend();
    }


    /**
     * 查询我点赞过的文章
     *
     * @param \
     * @return
     */
    @Override
    public List<UserCollectListVO> selectLike(Long userId) {
        log.debug("开始执行查询我点赞过的文章");
        /*Map<Long, Integer> articleStateByUser = likeCollectCacheRepository.getArticleStateByUser(userId);
        Map<Long, Integer> filteredMap = articleStateByUser.entrySet()
                .stream()
                .filter(v -> v.getValue() == 1 || v.getValue() == 3)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        List<UserCollectListVO> collectList = new ArrayList<>();
        filteredMap.keySet().stream().forEach(v -> {
            collectList.add(articleRepository.selectCollect(v));
        });*/
        List<UserCollectListVO> userListVO = articleRepository.selectLike(userId);
        return userListVO;
    }

    /**
     * 查询我收藏过的文章
     *
     * @param authorId
     * @return
     */
    @Override
    public List<UserCollectListVO> selectCollect(Long authorId) {
        log.debug("开始执行查询我收藏过的文章");
        /*Map<Long, Integer> articleStateByUser = likeCollectCacheRepository.getArticleStateByUser(userId);
        Map<Long, Integer> filteredMap = articleStateByUser.entrySet()
                .stream()
                .filter(v -> v.getValue() == 2 || v.getValue() == 3)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        List<UserCollectListVO> collectList = new ArrayList<>();
        filteredMap.keySet().stream().forEach(v -> {
            collectList.add(articleRepository.selectCollect(v));
        });*/
        List<UserCollectListVO> userCollectListVOS = articleRepository.selectCollect(authorId);
        return userCollectListVOS;
    }

    @Override
    public ArticleAuthorVO getAuthorByArticleId(Long id) {
        log.debug("开始处理【根据文章查询作者信息】的业务，参数：{}", id);
        ArticleAuthorVO authorResult = articleRepository.getAuthorByArticleId(id);
        if (authorResult == null) {
            String message = "查询作者信息详情失败，文章数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }
        return authorResult;
    }


    @Override
    public PageData<ArticleListItemVO> listByCategory(Long categoryId,Integer pageNum,Integer pageSize) {
        log.debug("开始处理【根据类别查询文章列表】的业务，类别Id: {}, 页码：{}，每页记录数：{}", categoryId,pageNum,pageSize);
        return articleRepository.listByCategory(categoryId,pageNum,pageSize);
    }




    @Override
    public void deleteById(Long id) {
        log.debug("开始处理【根据ID删除文章】的业务，参数：{}", id);
        ArticleStandardVO queryResult = articleRepository.getStandardById(id);
        if (queryResult == null) {
            String message = "删除文章失败，尝试删除的文章数据不存在！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND, message);
        }

        int rows = articleRepository.deleteById(id);
        if (rows != 1) {
            String message = "删除文章失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE, message);
        }

        rows = articleDetailRepository.deleteByArticle(id);
        if (rows != 1) {
            String message = "删除文章失败，服务器忙，请稍后再尝试！";
            log.warn(message);
            throw new ServiceException(ServiceCode.ERROR_DELETE, message);
        }

    }





}
